<?php


namespace models\Business\Tbk;


use Doctrine\DBAL\Exception\DriverException;
use models\Business\Member;
use models\DAO\AlibabafavourModel;
use models\DAO\TbkproductModel;
use models\Exception\Business\MemberException;
use models\Exception\Business\TbkproductException;
use models\Exception\DAO\ModelDriverException;
use models\Exception\DAO\ModelException;
use models\Exception\DAO\ModelReflectionException;
use models\Exception\DAO\ModelSqlException;
use models\Exception\Service\ServiceException;
use models\Exception\Transformer\TransformerException;
use models\Service\AlibabafavourService;
use models\Service\AlibabaproductService;
use models\Service\SystemService;
use models\Service\TbkfavourService;
use models\Service\TbkproductService;
use Yaf\Registry;

class TbkProduct
{
    /**
     * tbk商品采集入库
     * @param array $product_arr
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TransformerException
     */
    static public function collectTbkProduct($product_arr = []) {
        try {
            $update_data_arr = $insert_data_arr = $tbk_product_arr = [];
            $category_id_arr = array_column($product_arr, 'category_id');

            Registry::get('tbk_log')->info("待采集数据长度: " . count($product_arr));
            // 根据商品分类编号获取需要采集入库的数据
            if (!empty($category_id_arr)) {
                $sql = "SELECT tc.`id`, tcc.`collect_category_id` FROM `tbkcategorycarte` AS tcc LEFT JOIN `tbkcategory` AS tc ON tcc.`category_id` = tc.`id` WHERE tc.`stats` = 1 AND tcc.`collect_category_id` in ('" . implode("', '", $category_id_arr) . "')";
                $category_arr = TbkproductModel::getInstance()->getConn()->query($sql)->fetchAll();
                if (!empty($category_arr)) {
                    $category_id_match_arr = array_column($category_arr, 'id', 'collect_category_id');
                    foreach ($product_arr as $idx => $product_info) {
                        if (isset($category_id_match_arr[$product_info['category_id']])) {
                            $product_arr[$idx]['category_id'] = $category_id_match_arr[$product_info['category_id']];
                            // 拼接pid
                            $product_arr[$idx]['link'] .= '&pid=' . Registry::get('config')['application']['tbk']['pid'];
                            array_push($tbk_product_arr, $product_arr[$idx]);
                        } else
                            unset($product_arr[$idx]);
                    }
                }
            }
            Registry::get('tbk_log')->info("去除掉不需要采集的商品分类下的商品后长度: " . count($product_arr));
            $item_id_arr  = array_column($product_arr, 'product_id');

            // 查询商品是否存在
            if (count($product_arr) == 1) {
                $exists['data'] = TbkproductService::getInstance()->getOne(implode('', $item_id_arr));
            } else {
                $condition = ['groupOp' => 'AND', 'rules' => [
                    ['field' => 'product_id', 'op' => 'in', 'data' => implode(',', $item_id_arr)]]];
                $exists = TbkproductService::getInstance()->getList(1, count($product_arr), 'desc', 'product_id',
                    $condition);
            }

            if (!empty($exists['data'])) {
                $exists_product_id_arr = array_column($exists['data'], 'product_id');
                foreach ($product_arr as $idx => $product_info) {
                    // 已存在的商品写入更新数据
                    if (in_array($product_info['product_id'], $exists_product_id_arr)) {
                        array_push($update_data_arr, $product_info);
                    } // 不存在的商品写入插入数组
                    else {
                        array_push($insert_data_arr, $product_info);
                    }
                }
            } else
                $insert_data_arr = $product_arr;

            Registry::get('tbk_log')->info("新数据长度: " . count($insert_data_arr));
            Registry::get('tbk_log')->info("待修改数据长度: " . count($update_data_arr));

            // 更新数组存在
            if (!empty($update_data_arr)) {
                // 更新数组长度大于1，批量插入
                if (count($update_data_arr) > 1)
                    TbkproductService::getInstance()->batchUpdate($update_data_arr);
                // 更新数组长度等于1，单条更新
                else {
                    $update_arr = array_values($update_data_arr);
                    $update_arr = $update_arr[0];
                    $product_id = $update_arr['product_id'];
                    TbkproductService::getInstance()->update($update_arr, $product_id);
                }
            }

            // 插入数据存在
            if (!empty($insert_data_arr))
                // 批量插入
                TbkproductService::getInstance()->batchInsert($insert_data_arr);
        } catch (ModelDriverException $e) {
            throw $e;
        } catch (ModelException $e) {
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        }
    }

    /**
     * 获取淘宝客商品列表
     * @param array $parameters
     * @return array|mixed
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TbkproductException
     * @throws TransformerException
     */
    static public function getTbkProductList($parameters = []) {
        try {
            $rules = $condition = $groups = [];
            if (isset($parameters['product_id'])) {
                if (is_array($parameters['product_id']))
                    array_push($rules, ['field' => 'product_id', 'op' => 'in', 'data' => implode(",", $parameters['product_id'])]);
                else
                    array_push($rules, ['field' => 'product_id', 'op' => 'eq', 'data' => $parameters['product_id']]);
            }
            if (isset($parameters['recommend']))
                array_push($rules, ['field' => 'recommend', 'op' => 'eq', 'data' => $parameters['recommend']]);
            if (isset($parameters['title'])) {
                if (strpos($parameters['title'], ' ') !== false) {
                    $groups_arr = [];
                    foreach (explode(' ', $parameters['keyword']) as $keyword) {
                        array_push($groups_arr, ['field' => 'title', 'op' => 'nc', 'data' => '%' . $keyword . '%']);
                    }
                    if (!empty($groups_arr))
                        $groups = [
                            [
                                'groupOp' => 'OR',
                                'rules' => $groups_arr
                            ]
                        ];

                } else
                    array_push($rules, ['field' => 'title', 'op' => 'nc', 'data' => '%' . $parameters['title'] . '%']);
            }

            if (isset($parameters['category']) && $parameters['category'] != 0)
                array_push($rules, ['field' => 'category_id', 'op' => 'eq', 'data' => $parameters['category']]);

//            if (isset($parameters['title']))
//                array_push($rules, ['field' => 'title', 'op' => 'nc', 'data' => '%' . $parameters['title'] . '%']);

            if (isset($parameters['from_api']) && $parameters['from_api'] === true) {
                array_push($rules, ['field' => 'stats', 'op' => 'eq', 'data' => 1]);
                if (! isset($parameters['from_favour']) || $parameters['from_favour'] === false) {
                    array_push($rules, ['field' => 'coupon_start_time', 'op' => 'le', 'data' => date('Y-m-d', time() + 86400)]);
                    array_push($rules, ['field' => 'coupon_end_time', 'op' => 'ge', 'data' => date('Y-m-d', time() + 86400)]);
                }
            }
            else{
                if (isset($parameters['stats']))
                    array_push($rules, ['field' => 'stats', 'op' => 'eq', 'data' => $parameters['stats']]);
                if (isset($parameters['coupon_start_time'])){
                    array_push($rules, ['field' => 'coupon_start_time', 'op' => 'le', 'data' => date("Y-m-d 00:00:00", strtotime(str_replace('/', '-', $parameters['coupon_start_time'])))]);
                }

                if (isset($parameters['coupon_end_time'])){
                    array_push($rules, ['field' => 'coupon_end_time', 'op' => 'ge', 'data' => date("Y-m-d 23:59:59", strtotime(str_replace('/', '-', $parameters['coupon_end_time'])))]);
                }

            }


            if (!empty($rules))
                $condition = ['groupOp' => 'AND', 'rules' => $rules];
            if (!empty($groups))
                $condition['groups'] = $groups;

            $product_list = TbkproductService::getInstance()->getList(
                isset($parameters['page']) ? $parameters['page'] : 1,
                isset($parameters['page_size']) ? $parameters['page_size'] : 10,
                isset($parameters['sort']) ? $parameters['sort'] : 'desc',
                isset($parameters['order']) ? $parameters['order'] : 'sales',
                $condition
            );
            if (empty($product_list['data']))
                throw new TbkproductException(TbkproductException::TBKPRODUCT_IS_NOT_EXISTS, TbkproductException::TBKPRODUCT_IS_NOT_EXISTS_NO);

            $product_list = TbkCategory::getCategoriesByModules($product_list);

            $system  = SystemService::getInstance()->getOne(1);
            $system_price_rate = $system['rebate_rate'] ? $system['rebate_rate'] : 0.00;
            $parent_rebate_rate = $system['tbk_parent_rate'] ? $system['tbk_parent_rate'] : 0.00;
            $grand_rebate_rate = $system['tbk_sub_rate'] ? $system['tbk_sub_rate'] : 0.00;

            foreach ($product_list['data'] as $idx => $product_info) {
                $product_list['data'][$idx]['rebate_integral'] = sprintf('%.2f', $product_info['commission'] * $system_price_rate / 100);
                $product_list['data'][$idx]['parent_rebate'] = sprintf('%.2f', $product_info['commission'] * $parent_rebate_rate / 100);
                $product_list['data'][$idx]['grand_parent_rebate'] = sprintf('%.2f', $product_info['commission'] * $grand_rebate_rate / 100);
                $product_list['data'][$idx]['recommend'] = (int)$product_info['recommend'];
                $product_list['data'][$idx]['stats'] = (int)$product_info['stats'];
                if (strpos($product_info['pic'], 'http://') === false && strpos($product_info['pic'], 'https://') === false){
                    $product_list['data'][$idx]['pic'] = Registry::get('config')['application']['host'] . $product_info['pic'];
                }
                if (strpos($product_info['image'], 'http://') === false && strpos($product_info['image'], 'https://') === false){
                    $product_list['data'][$idx]['image'] = 'http://img.haodanku.com/' . $product_info['image'];
                }

                $product_list['data'][$idx]['link'] = strpos($product_list['data'][$idx]['link'], '&pid=') === false ?
                    $product_list['data'][$idx]['link'] . '&pid=' . Registry::get('config')['application']['tbk']['pid'] : $product_list['data'][$idx]['link'];
            }

            if (isset($parameters['from_api']) && $parameters['from_api'] === true)
                $product_list = Member::getFavoursByProductLists($product_list, 1);

            return $product_list;
        } catch (ModelDriverException $e) {
            if ($e->getCode() == ModelDriverException::DRIVER_EXCEPTION_MSG_NO)
                throw new TbkproductException(TbkproductException::TBKPRODUCT_IS_NOT_EXISTS, TbkproductException::TBKPRODUCT_IS_NOT_EXISTS_NO);
            throw $e;
        } catch (ModelException $e) {
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        }
    }

    /**
     * 通过product_id读取tbkproduct中的数据
     * @param $product_id
     * @return array|mixed|null
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TbkproductException
     * @throws TransformerException
     */
    static public function getTbkProductByProductId($product_id) {
        try {
            if (empty($product_id))
                throw new TbkproductException(TbkproductException::TBKPRODUCT_ID_IS_EMPTY, TbkproductException::TBKPRODUCT_ID_IS_EMPTY_NO);

            $product_info = TbkproductService::getInstance()->getOne($product_id);

            $product_info['link'] = strpos($product_info['link'], '&pid=') === false ?
                $product_info['link'] . '&pid=' . Registry::get('config')['application']['tbk']['pid'] : $product_info['link'];

            $product_info = TbkCategory::getCategoriesByModules(['data' => [$product_info]]);

            $system  = SystemService::getInstance()->getOne(1);
            $system_price_rate = $system['tbk_rebate_rate'] ? $system['tbk_rebate_rate'] : 0.00;
            $parent_rebate_rate = $system['tbk_parent_rate'] ? $system['tbk_parent_rate'] : 0.00;
            $grand_rebate_rate = $system['tbk_sub_rate'] ? $system['tbk_sub_rate'] : 0.00;

            $product_info['data'][0]['rebate_integral'] = sprintf('%.2f', $product_info['data'][0]['commission'] * $system_price_rate / 100);
            $product_info['data'][0]['parent_rebate'] = sprintf('%.2f', $product_info['data'][0]['commission'] * $parent_rebate_rate / 100);
            $product_info['data'][0]['grand_parent_rebate'] = sprintf('%.2f', $product_info['data'][0]['commission'] * $grand_rebate_rate / 100);

            if (strpos($product_info['data'][0]['image'], 'http://') === false && strpos($product_info['data'][0]['image'], 'https://') === false)
                $product_info['data'][0]['image'] = 'http://img.haodanku.com/' . $product_info['data'][0]['image'];

            if (Registry::get('jwt_info')->id) {
                $product_info = Member::getFavoursByProductLists($product_info, 1);
            } else
                $product_info['data'][0]['is_favour'] = 0;

            return $product_info;
        } catch (TbkproductException $e) {
            throw $e;
        } catch (ModelDriverException $e) {
            if ($e->getCode() == ModelDriverException::DRIVER_EXCEPTION_MSG_NO)
                throw new TbkproductException(TbkproductException::TBKPRODUCT_IS_NOT_EXISTS, TbkproductException::TBKPRODUCT_IS_NOT_EXISTS_NO);
            throw $e;
        } catch (ModelException $e) {
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        }
    }

    /**
     * 编辑tbkproduct
     * @param array $parameters
     * @return array|mixed|null
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TbkproductException
     * @throws TransformerException
     */
    static public function editTbkProduct($parameters = [])
    {
        try {
            if (!isset($parameters['product_id']) || empty($parameters['product_id']))
                throw new TbkproductException(TbkproductException::TBKPRODUCT_ID_IS_EMPTY, TbkproductException::TBKPRODUCT_ID_IS_EMPTY_NO);

            $update_arr = [];
            if (isset($parameters['type']))
                $update_arr['type'] = $parameters['type'];
            if (isset($parameters['category_id']))
                $update_arr['category_id'] = $parameters['category_id'];
            if (isset($parameters['title']))
                $update_arr['title'] = $parameters['title'];
            if (isset($parameters['short_title']))
                $update_arr['short_title'] = $parameters['short_title'];
            if (isset($parameters['desc']))
                $update_arr['desc'] = $parameters['desc'];
            if (isset($parameters['article']))
                $update_arr['article'] = $parameters['article'];
            if (isset($parameters['link']))
                $update_arr['link'] = $parameters['link'];
            if (isset($parameters['pic'])) {
                if (strpos($parameters['pic'], Registry::get('config')['application']['host']) !== false)
                    $update_arr['pic'] = str_replace(Registry::get('config')['application']['host'], '', $parameters['pic']);
                else
                    $update_arr['pic'] = $parameters['pic'];
            }

            if (isset($parameters['image'])) {
                if (strpos($parameters['image'], Registry::get('config')['application']['host']) !== false)
                    $update_arr['image'] = str_replace(Registry::get('config')['application']['host'], '', $parameters['image']);
                else
                    $update_arr['image'] = $parameters['image'];
            }

            if (isset($parameters['stats']))
                $update_arr['stats'] = $parameters['stats'];
            if (isset($parameters['recommend']))
                $update_arr['recommend'] = $parameters['recommend'];
            if (isset($parameters['price']))
                $update_arr['price'] = $parameters['price'];
            if (isset($parameters['today_sales']))
                $update_arr['today_sales'] = $parameters['today_sales'];
            if (isset($parameters['sales']))
                $update_arr['sales'] = $parameters['sales'];
            if (isset($parameters['sales_in_2_hours']))
                $update_arr['sales_in_2_hours'] = $parameters['sales_in_2_hours'];
            if (isset($parameters['activity_type']))
                $update_arr['activity_type'] = $parameters['activity_type'];
            if (isset($parameters['activity_link']))
                $update_arr['activity_link'] = $parameters['activity_link'];
            if (isset($parameters['coupon_start_time']))
                $update_arr['coupon_start_time'] = $parameters['coupon_start_time'];
            if (isset($parameters['coupon_end_time']))
                $update_arr['coupon_end_time'] = $parameters['coupon_end_time'];
            if (isset($parameters['coupon_receive']))
                $update_arr['coupon_receive'] = $parameters['coupon_receive'];
            if (isset($parameters['coupon_num']))
                $update_arr['coupon_num'] = $parameters['coupon_num'];

            if (!empty($update_arr)) {
                $update_arr['updated_at'] = date('Y-m-d H:i:s', time());
                $tbk_product          = TbkproductService::getInstance()->update($update_arr, $parameters['product_id']);
            } else
                $tbk_product = TbkproductService::getInstance()->getOne($parameters['product_id']);

            return $tbk_product;
        } catch (ModelDriverException $e) {
            if ($e->getCode() == ModelDriverException::DRIVER_EXCEPTION_MSG_NO)
                throw new TbkproductException(TbkproductException::TBKPRODUCT_EDIT_FAILURE, TbkproductException::TBKPRODUCT_EDIT_FAILURE_NO);

            throw $e;
        } catch (ModelException $e) {
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        }
    }

    /**
     * 领券
     * @param array $parameters
     * @return bool
     * @throws ModelSqlException
     * @throws TbkproductException
     */
    static public function decrProductCoupon($parameters = []) {
        $conn = TbkproductModel::getInstance()->getConn();
        $conn->beginTransaction();
        try {
            if (!isset($parameters['id']) || empty($parameters['id']))
                throw new TbkproductException(TbkproductException::TBKPRODUCT_ID_IS_EMPTY, TbkproductException::TBKPRODUCT_ID_IS_EMPTY_NO);

            $sql = "UPDATE `tbkproduct` SET `coupon_receive` = `coupon_receive` + 1, `coupon_num` = `coupon_num` - 1 WHERE `product_id` = '" . $parameters['id'] . "'";
            Registry::get('tbk_log')->info("减少优惠券库存sql: " . $sql);
            $conn->executeQuery($sql);
            $conn->commit();

            return true;
        } catch (TbkproductException $e) {
            throw $e;
        } catch (\Exception $e) {
            $conn->rollBack();
            Registry::get('tbk_log')->err("减少优惠券库存失败");
//            throw $e;
        }
    }

    static public function searchFromHDK($parameters) {
        if (isset($parameters['title']) && !empty($parameters['title']))
            $product_list = Haodanku::searchProduct($parameters['title'], $parameters['page'], $parameters['page_size']);
        else if (isset($parameters['product_id']) && !empty($parameters['product_id']))
            $product_list = Haodanku::searchProduct($parameters['product_id'], $parameters['page'], $parameters['page_size']);
        if (empty($product_list))
            throw new TbkproductException(TbkproductException::TBKPRODUCT_IS_NOT_EXISTS, TbkproductException::TBKPRODUCT_IS_NOT_EXISTS_NO);

        $system  = SystemService::getInstance()->getOne(1);
        $system_price_rate = $system['rebate_rate'] ? $system['rebate_rate'] : 0.00;
        $parent_rebate_rate = $system['tbk_parent_rate'] ? $system['tbk_parent_rate'] : 0.00;
        $grand_rebate_rate = $system['tbk_sub_rate'] ? $system['tbk_sub_rate'] : 0.00;

        foreach ($product_list['data'] as $idx => $product_info) {
            $product_list['data'][$idx]['type'] = 0;
            $product_list['data'][$idx]['is_favour'] = 0;

            $product_list['data'][$idx]['rebate_integral'] = sprintf('%.2f', $product_info['commission'] * $system_price_rate / 100);
            $product_list['data'][$idx]['parent_rebate'] = sprintf('%.2f', $product_info['commission'] * $parent_rebate_rate / 100);
            $product_list['data'][$idx]['grand_parent_rebate'] = sprintf('%.2f', $product_info['commission'] * $grand_rebate_rate / 100);
            $product_list['data'][$idx]['link'] = strpos($product_list['data'][$idx]['link'], '&pid=') === false ?
                $product_list['data'][$idx]['link'] . '&pid=' . Registry::get('config')['application']['tbk']['pid'] : $product_list['data'][$idx]['link'];

        }

        return $product_list;
    }
}
